package dao

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

//状态码
type StatusRes struct {
	Status int `json:"status"`
}

//错误状态码
type StatusErrorRes struct {
	Status int `json:"status"`
	Error  struct {
		RootCause struct {
			Type   string `json:"type"`
			Reason string `json:"reason"`
		} `json:"root_cause"`
		Type   string `json:"type"`
		Reason string `json:"reason"`
	} `json:"error"`
}

//创建
type CreateRes struct {
	Acknowledged       bool   `json:"acknowledged"`
	ShardsAcknowledged bool   `json:"shards_acknowledged"`
	Index              string `json:"index"`
}

//删除
type DelRes struct {
	Acknowledged bool `json:"acknowledged"`
}

//Mapping
type MappingRes struct {
	Acknowledged bool `json:"acknowledged"`
}

//搜索
type SearchRes struct {
}

//保存数据或更新
type SaveRes struct {
	Index   string `json:"_index"`
	Types   string `json:"_type"`
	Id      string `json:"_id"`
	Version int    `json:"_version"`
	Result  string `json:"result"`
	Shards  struct {
		Total      int `json:"total"`
		Successful int `json:"successful"`
		Failed     int `json:"failed"`
	} `json:"_shards"`
	SeqNo       int `json:"_seq_no"`
	PrimaryTerm int `json:"_primary_term"`
}

//
type ESPosts struct {
	Id           int    `json:"id"`
	Author       int    `json:"author"`
	PostType     int    `json:"post_type"`
	Title        string `json:"title"`
	Content      string `json:"content"`
	ReadNum      int    `json:"read_num"`
	IsPrivate    uint   `json:"is_private"`
	IsShow       uint   `json:"is_show"`
	IsRemark     uint   `json:"is_remark"`
	IsTemp       uint   `json:"is_temp"`
	IsStar       uint   `json:"is_star"`
	AddTime      string `json:"add_time"`
	LastEditTime string `json:"last_edit_time"`
}

/**
 * 查看集群中都有哪些索引
 */
func EsIndices() {

}

/**
 * 创建索引
 */
func EsIndexCreate(indexName string) (err error) {
	url := EsConf["URL"] + "/" + indexName
	client := &http.Client{}
	putBody := strings.NewReader(`{"settings":{"number_of_shards":2,"number_of_replicas":1}}`)
	request, err := http.NewRequest("PUT", url, putBody)
	if err != nil {
		return
	}
	request.Header.Add("Content-Type", "application/json")
	response, err := client.Do(request)
	if err != nil {
		return
	}

	var body []byte
	body, err = ioutil.ReadAll(response.Body)
	if err != nil {
		return
	}

	var result = CreateRes{}
	err = json.Unmarshal(body, &result)
	if err != nil {
		return
	}

	if result.Acknowledged != true {
		err = errors.New("Create failed：" + string(body))
		return
	}

	return
}

/**
 * 删除索引
 */
func EsIndexDelete(indexName string) (err error) {
	url := EsConf["URL"] + "/" + indexName
	client := &http.Client{}
	request, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return
	}
	response, err := client.Do(request)
	if err != nil {
		return
	}

	var body []byte
	body, err = ioutil.ReadAll(response.Body)
	if err != nil {
		return
	}

	var result = DelRes{}
	err = json.Unmarshal(body, &result)
	if err != nil {
		return
	}
	if result.Acknowledged != true {
		err = errors.New("Delete failed：" + string(body))
		return
	}
	return
}

/**
Mapping
*/
func EsIndexMapping(indexName, mapping string) (err error) {
	url := EsConf["URL"] + "/" + indexName + "/" + indexName + "/_mapping?pretty"
	client := &http.Client{}
	request, err := http.NewRequest("PUT", url, strings.NewReader(mapping))
	if err != nil {
		return
	}
	request.Header.Set("Content-type", "application/json")
	response, err := client.Do(request)
	if err != nil {
		return
	}

	var body []byte
	body, err = ioutil.ReadAll(response.Body)
	if err != nil {
		return
	}

	var result = MappingRes{}
	err = json.Unmarshal(body, &result)
	if err != nil {
		return
	}
	if result.Acknowledged != true {
		err = errors.New("Mapping失败：" + string(body))
		return
	}

	return
}

func EsIndexSaveData(indexName, typeName, data string, pk int) (err error) {
	url := fmt.Sprintf("%s/%s/%s/%d", EsConf["URL"], indexName, typeName, pk)

	request, err := http.NewRequest("PUT", url, strings.NewReader(data))
	if err != nil {
		return
	}
	request.Header.Set("Content-type", "application/json")
	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return
	}
	var body []byte
	body, err = ioutil.ReadAll(response.Body)
	if err != nil {
		return
	}

	fmt.Println(string(body))

	statusRes := StatusRes{}
	json.Unmarshal(body, &statusRes)
	if statusRes.Status > 0 {
		var StatusError StatusErrorRes
		json.Unmarshal(body, &StatusError)
		str, _ := json.Marshal(StatusError)
		return errors.New(string(str))
	} else {
		var sRes SaveRes
		json.Unmarshal(body, &sRes)
		if sRes.Shards.Total >= 1 {
			return
		} else {
			str, _ := json.Marshal(sRes)
			return errors.New(string(str))
		}
	}

	return
}

func EsIndexReBuild() {

}

func EsIndexAll() (err error) {

	return
}

func EsIndexMultiSave(str string) (err error) {
	return
}
